#pragma once
#ifndef __DRIVER_H__
#define __DRIVER_H__

#include <stdint.h>

#include "cfslb_event.h"
#include "common.h"
#include "driver_common.h"
#include "list.h"

typedef struct driver driver_stru;
typedef struct driver_frw driver_frw_stru;
typedef struct driver_ops driver_ops_stru;

typedef struct driver_frw {
    list_t  list;
    const char* name;
    void* priv;
    int (*init)(driver_frw_stru* frw);
    int (*ready)(driver_frw_stru* frw);
    int (*exit)(driver_frw_stru* frw);
    int (*match)(const driver_stru* driver, void* driver_priv);
} driver_frw_stru;

typedef struct driver_ops {
    driver_frw_stru* frw;
    int (*add_iface)(driver_stru* drv, driver_iface_add_param_stru* param);
    int (*del_iface)(driver_stru* drv);
    int (*cfg_iface)(driver_stru* drv, driver_iface_param_stru* param);
    int (*start_iface)(driver_stru* drv);
    int (*stop_iface)(driver_stru* drv);

    int (*scan)(driver_stru* drv, driver_scan_param_stru* param);
    int (*abort_scan)(driver_stru* drv);
    int (*connect)(driver_stru* drv, driver_connect_param_stru* param);
    int (*disconnect)(driver_stru* drv);
    int (*kick)(driver_stru* drv, const char addr[6]);

    // acn
    int (*enable_vendor_ie)(driver_stru* drv, const void* data, int len);
    int (*disable_vendor_ie)(driver_stru* drv);
    int (*mgmt_tx)(driver_stru* drv, const void* data, int len);
} driver_ops_stru;

int driver_report_event(driver_frw_stru* frw, void* driver_priv, driver_event_stru* event, int size);

typedef int (*driver_event_cb)(void* p_iface, driver_event_stru* event, int size);
typedef struct driver {
    list_t  entry;
    driver_event_cb event_cb;
    void* iface;  // for upper [iface] using
    void* priv;   // for lower [adapter] using
    driver_ops_stru* ops;
} driver_stru;

int driver_frw_init(driver_frw_stru* frw);
int driver_frw_exit(driver_frw_stru* frw);
int driver_frw_ready(driver_frw_stru* frw);

int driver_add_iface(driver_stru* driver, const char* driver_name,
    char* iface_name, driver_event_cb cb, void* priv, uint8_t mode);
int driver_del_iface(driver_stru* driver);
int driver_cfg_iface(driver_stru* driver, driver_iface_param_stru* param);
int driver_start_iface(driver_stru* drv, const char* name);
int driver_stop_iface(driver_stru* drv, const char* name);
int driver_scan(driver_stru* driver, driver_scan_param_stru* param);
int driver_scan_abort(driver_stru* driver);
int driver_connect(driver_stru* driver, driver_connect_param_stru* param);
int driver_disconnect(driver_stru* driver);
int driver_enable_vendor_ie(driver_stru* driver, const void* data, int len);
int driver_disable_vendor_ie(driver_stru* driver);
int driver_mgmt_tx(driver_stru* driver, const void* data, int len);

int driver_ops_completed(void);
#endif
